#include "dataprocessservice.h"
#include "log.h"
#include "CustomEvent.h"
#include "mainwindow.h"

DataProcessService::DataProcessService(const hv::SocketChannelPtr& channel, QObject *parent) : QObject(parent), channel(channel)
{
    memset(&psm_custom, 0X00, sizeof(psm_custom));
    memset(&psm_default, 0X00, sizeof(psm_default));

    psm_default.buf     = new uint8_t[512];
    psm_default.bufsize = 512;

    psm_default.recv_callback = recv_callback;

    psm_default.identifier[0]    = '#';
    psm_default.identifier[1]    = '#';
    psm_default.identifier_bytes = 2;

    psm_default.delimiter[0]       = '\r';
    psm_default.delimiter[1]       = '\n';
    psm_default.delimiter_bytes    = 2;

    psm_default.arg = (void *)&channel;

    psm_custom.buf     = new uint8_t[512];
    psm_custom.bufsize = 512;

    psm_custom.recv_callback = recv_callback;

    psm_custom.identifier[0]    = 0XB0;
    psm_custom.identifier[1]    = 0XA1;
    psm_custom.identifier_bytes = 2;

    psm_custom.body_offset = 6;

    psm_custom.length_field_bytes  = 2;
    psm_custom.length_field_offset = 4;
    psm_custom.length_field_coding = PSM_UNPACK_ENCODE_BY_LITTEL_ENDIAN;

    psm_custom.arg = (void *)&channel;
}

DataProcessService::~DataProcessService()
{
    delete [] psm_default.buf;
    delete [] psm_custom.buf;
}

void DataProcessService::process(const void* buf, uint32_t len)
{
    psm_recv(&psm_custom, buf, len);
    psm_recv(&psm_default, buf, len);
    psm_unpack(&psm_custom);
    psm_unpack(&psm_default);
}

int DataProcessService::recv_callback(psm_t* psm, const void* data, uint32_t len)
{
    uint8_t* buf = (uint8_t *)data;
    uint32_t size = len;

    if(buf[0] == (uint8_t)0XB0 && buf[1] == (uint8_t)0XA1)
    {
        uint16_t cmd = (buf[3] << 8) | buf[2];
//        uint16_t len = (buf[5] << 8) | buf[4];
//        uint16_t crc = (buf[size - 1] << 8) | buf[size - 2];

        switch(cmd)
        {

        case 0:
        {
            QByteArray imei((const char *)&buf[6], 15);
            QByteArray time((const char *)&buf[21], 20);

            hv::SocketChannelPtr channel = *(hv::SocketChannelPtr *)psm->arg;

            DeviceHeartbeatEvent e(channel, imei);
            g_MainWnd->postEvent(e);

            LOGI("<%s><%s><heartbeat>", time.data(), imei.data());

            break;
        }

        case 2:
        {
            const static QStringList l = {"Online", "Offline", "Lock", "Unlock", "Power Supply", "Battery Supply", "Dead Battery"};
            QByteArray imei((const char *)&buf[6], 15);
            QByteArray time((const char *)&buf[21], 20);
            uint8_t state = buf[41];
            uint8_t SL = state & 0X0F;
            uint8_t SH = (state >> 4) & 0X0F;
            if(SH != 0)
            {
                LOGI("<%s><%s><state>:Probe %d %s", time.data(), imei.data(), SH, l[SL].toStdString().c_str());
            }else
            {
                LOGI("<%s><%s><state>:%s", time.data(), imei.data(), l[SL].toStdString().c_str());
            }
        }

        default:break;
        }
    }else
    {
        buf[size - 2] = 0;  // 去除包尾的回车换行符
        LOGI("\"%s\\r\\n\"", buf);
    }

    return 0;
}
